/*
 * -------------------------------------------------------------------------
 * 插件管理器
 * -------------------------------------------------------------------------
 */

/*app对象实例*/
let app;
const _          = require('lodash');
const fs         = require('fs');
const os         = require('os');
const path       = require('path');
const is         = require('../helper/is');
const electron   = require('electron');
const { exec }   = require('child_process');
const IPC_PLUGIN = require('../src/ipc/dict').IPC_PLUGIN;
const ipcMain    = electron.ipcMain;

/**
 * 插件配置
 * @type {[{discription: string, exe: string, name: string}]}
 * @description 每个新增插件，需要在此列表中声明
 * @description plugins[n].name        插件名
 * @description plugins[n].discription 插件描述
 * @description plugins[n].exe         插件可执行文件名
 * @description 插件存放目录 `./softs/插件名/`
 * @description 图标存放目录 `./icons/插件名.png`
 */
const plugins = [
    {
        // name       : 'FastStoneCapture',
        // discription: '强大的前端工具，支持捕捉屏幕、窗口、对象、矩形区域、异形区域、滚动区域、固定区域、屏幕录像、屏幕聚焦、放大镜、屏幕取色、十字线、屏幕标尺、获取扫描仪图像、图片PDF、图片合并、图片编辑器等功能。',
        // exe        : 'FSCapture.exe'
    }
];

/**
 * 初始化
 * @param appInstance
 */
function initialize (appInstance) {
    /*复写app实例*/
    app = appInstance;
    
    /*渲染进程获取插件列表*/
    ipcMain.on(IPC_PLUGIN.GETLISTS, putList);
    
    /*渲染进程执行插件*/
    ipcMain.on(IPC_PLUGIN.EXECUTIVE, (e, name) => executive(name));
}

/**
 * 获取插件列表
 * @return {*[]}
 */
function getLists () {
    let lists = [];
    for (const k in plugins) {
        let base64 = '';
        let icon   = path.resolve(getBaseDir(), 'plugins', 'icons', `${plugins[k].name}.png`);
        
        /*读取icon的base64*/
        if (fs.existsSync(icon)) {
            base64 = `data:image/png;base64,${Buffer.from(fs.readFileSync(icon)).toString('base64')}`;
        }
        
        lists.push({
            name       : plugins[k].name,
            discription: plugins[k].discription,
            icon       : base64
        });
    }
    return lists;
}

/**
 * 运行插件
 * @param name
 */
function executive (name) {
    /*查找插件*/
    const key = _.findIndex(plugins, { name });
    
    /*插件不存在*/
    if (key < 0) return executiveResult({
        errCode: 1,
        errMsg : '插件未注册'
    });
    
    /*插件路径*/
    const file = path.resolve(getBaseDir(), 'plugins', 'softs', plugins[key].name, plugins[key].exe);
    
    /*插件不存在*/
    if (!fs.existsSync(file)) return executiveResult({
        errCode: 1,
        errMsg : '插件不存在'
    });
    
    /*最大等待启动时间（秒）*/
    let waitSecond = 10;
    
    /*启动耗费时间（秒）*/
    let useSecond = 0;
    
    /*启动插件*/
    exec(file);
    
    /*检测插件是否启动成功*/
    let checkProgram = setInterval(() => {
        ++useSecond;
        
        if (useSecond > waitSecond) {
            clearInterval(checkProgram);
            return executiveResult({
                errCode: 1,
                errMsg : '插件启动超时'
            });
        }
        
        exec('tasklist /FO CSV', (err, out) => {
            if (err) return executiveResult({
                errCode: 1,
                errMsg : '插件启动状态验证失败'
            });
            
            /*检测程序运行列表中的安装包进程*/
            out.split(os.EOL).map(line => {
                if (line.indexOf(`"${path.basename(file)}"`) === 0) {
                    clearInterval(checkProgram);
                    return executiveResult({
                        errCode: 0,
                        errMsg : '插件已启动'
                    });
                }
            });
        });
    }, 500);
}

/**
 * 将插件列表通知到渲染进程
 */
function putList () {
    app.$windowMain.webContents.send(IPC_PLUGIN.PUTLISTS, getLists());
}

/**
 * 将插件执行结果通知到渲染进程
 * @param res
 * @return {*}
 */
function executiveResult (res) {
    app.$windowMain.webContents.send(IPC_PLUGIN.EXECUTIVE_RESULT, res);
    return res;
}

/**
 * 获取基本目录
 * @return {string}
 */
function getBaseDir () {
    return is.electronDev() ? path.resolve(__dirname, '..') : path.resolve(path.dirname(app.getPath('exe')));
}

/**
 * 导出
 * @type {{initialize: initialize}}
 */
module.exports = {
    initialize
};
